package com.qijian.mold.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.SecurityUtils;
import com.qijian.maindata.service.IAdjustFieldsService;
import com.qijian.mold.domain.dto.GetMoldDto;
import com.qijian.mold.domain.dto.GetUserDetailsByRoleTypeDto;
import com.qijian.mold.domain.dto.SelectTaskDto;
import com.qijian.mold.domain.entity.*;
import com.qijian.mold.domain.param.mold.GetMoldParam;
import com.qijian.mold.domain.param.task.*;
import com.qijian.mold.domain.vo.mold.MoldDetailsVo;
import com.qijian.mold.domain.vo.moldChange.EqpVo;
import com.qijian.mold.domain.vo.task.TaskDetailsVo;
import com.qijian.mold.domain.vo.task.TaskListVo;
import com.qijian.mold.domain.vo.user.UserDetailsVo;
import com.qijian.mold.enums.*;
import com.qijian.mold.repository.*;
import com.qijian.mold.service.MoldChangeLogService;
import com.qijian.mold.service.MoldChangeTaskService;
import com.qijian.mold.util.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 换模任务
 *
 * @author anni.zhu
 * @author anni.zhu@king-v.com
 * Created in 2025/3/29 17:25
 */
@Service
public class MoldChangeTaskServiceImpl implements MoldChangeTaskService {

    @Autowired
    private MoldChangeTaskRepository taskRepository;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private TaskChangeDetailsRepository taskChangeDetailsRepository;
    @Autowired
    private MoldEqpMpRepository eqpMoldMpRepository;
    @Autowired
    private TaskUserMpRepository userMpRepository;
    @Autowired
    private MoldChangeRepository moldChangeRepository;
    @Autowired
    private MoldChangeLogService logService;
    @Autowired
    private MoldRepository moldRepository;

    /**
     * 校验任务
     * 该用户已经有进行中的上下模任务是不允许创建上下模任务的
     */
    void checkTask(Long moldChangeId) {
        List<MoldChangeTask> tasks = taskRepository.getBaseMapper().selectList(
                new LambdaQueryWrapper<MoldChangeTask>()
                        .eq(MoldChangeTask::getMoldChangeId, moldChangeId)
                        .eq(MoldChangeTask::getIsDel, 0)
                        .eq(MoldChangeTask::getStatus, MoldChangeStatusEnum.IN_PROGRESS.getId()));
        if (CollectionUtil.isNotEmpty(tasks)) {
            throw new ServiceException("该申请单已有进行中的换模任务，请先完成之前的任务");
        }
    }

    void checkRole(Long userId, EqpVo eqpDetail) {
//        //检查是否admin角色
//        Boolean isAdmin = moldChangeRepository.getMoleRoleByUserId(userId, MoldRoleEnum.ADMIN.getName());
//        if (!isAdmin) {
//            //检查该用户是是操作员并且符合该工段
//            Boolean isOperator = moldChangeRepository.getOperatorByLocationId(MoldRoleEnum.WORKER.getName(), eqpDetail.getLocationId(), userId);
//            if (!isOperator) {
//                throw new ServiceException("您没有权限操作该设备,只有角色是操作工,工段是" + eqpDetail.getLocation() + "的用户才能操作");
//            }
//        }
    }

    /**
     * 创建上模任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUp(CreateUpTaskParam param) {
        Long userId = SecurityUtils.getUserId();

        //校验任务
        checkTask(param.getMoldChangeId());

        //根据设备id获取设备信息
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(param.getEqpId());
        if (eqpDetail == null) {
            throw new ServiceException("设备不存在");
        }

        //检查权限
//        checkRole(userId, eqpDetail);

        //检查模具是否都是空闲状态
        moldRepository.listByIds(param.getMoldIds()).forEach(mold -> {
            if (mold.getStatus() != MoldStatusEnum.FREE.getId()) {
                throw new ServiceException("无法添加该模具,模具" + mold.getName() + "不是空闲状态");
            }
        });

        MoldChange moldChange = moldChangeRepository.getById(param.getMoldChangeId());
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        if (!moldChange.getTechConfirmUserIds().contains(userId.toString())) {
            throw new ServiceException("您没有权限操作该设备");
        }
        BeanUtils.copyProperties(eqpDetail, moldChange);
        moldChange.setType(MoldChangeLogTypesEnum.MOLD_CHANGE_DEBUG.getId());
        moldChange.setTypeStatus(MoldChangeStatusEnum.IN_PROGRESS.getId());
        moldChange.setDetailsType(MoldChangeLogDetailsTypesEnum.START_MOLD.getId());

        //需要把当前用户加入到换修申请单得可见人ids中去
        List<Long> visibleUserIds = new ArrayList<>();
        visibleUserIds.add(userId);
        moldChange.setVisibleUserIds(JSONArray.toJSONString(visibleUserIds));

        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }

        //创建任务
        MoldChangeTask task = new MoldChangeTask();
        BeanUtils.copyProperties(param, task);
        BeanUtils.copyProperties(eqpDetail, task);
        task.setStartTime(LocalDateTime.now());
        task.setType(MoldChangeTaskTypeEnum.UP.getId());
        Long id = IdGenerator.SNOW.generate();
        task.setId(id);
        String code = getCode(MoldChangeTaskTypeEnum.UP);
        task.setCode(code);
        task.setOperatorId(userId);
        task.setMoldChangeId(moldChange.getId());
        task.setStatus(MoldChangeStatusEnum.IN_PROGRESS.getId());
        if (!taskRepository.save(task)) {
            throw new ServiceException("创建上模任务失败");
        }

        //拿到技术部确认的ids，添加任务用户关联
//        List<Long> ids = JSONArray.parseArray(moldChange.getTechConfirmUserIds(), Long.class);
//        if (ids == null || ids.isEmpty()) {
//            throw new ServiceException("技术部确认人员为空");
//        }
//        saveTaskUserMp(ids, id);

        //把当前创建用户添加到任务关联
        List<Long> ids = new ArrayList<>();
        ids.add(userId);
        saveTaskUserMp(ids, id);

        //模具的ids
        saveMoldMp(MoldChangeTaskTypeEnum.UP.getId(), param.getMoldChangeId(), id, param.getEqpId(), param.getMoldIds());
        //添加日志
        logService.saveTaskLog(id, moldChange.getId(), userId, MoldChangeLogDetailsTypesEnum.START_MOLD, null);
    }

    /**
     * 生成编号：
     *
     * @return
     */
    private String getCode(MoldChangeTaskTypeEnum type) {
        HashOperations<String, String, String> hash = stringRedisTemplate.opsForHash();
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String taskCode = "";
        if (type.getId() == MoldChangeTaskTypeEnum.UP.getId()) {
            taskCode = "MU";
        } else {
            taskCode = "MD";
        }
        Long value = taskRepository.getBaseMapper().selectCount(
                new LambdaQueryWrapper<MoldChangeTask>()
                        .eq(MoldChangeTask::getType, type.getId())
                        .eq(MoldChangeTask::getIsDel, 0)
                        .like(MoldChangeTask::getCreateTime, sdf.format(now)));

        sdf = new SimpleDateFormat("yyyyMMdd");
        String leftCode = taskCode + sdf.format(now);
        String rightCode = String.format("%03d", (value + 1));
        String code = leftCode + rightCode;
        while (!hash.putIfAbsent("ProcurementPlan", code, code)) {
            //前10位是固定的，后三位是数量，不足三位补0
            rightCode = code.substring(11);
            int number = Integer.valueOf(rightCode);
            rightCode = String.format("%03d", (number + 1));
            code = leftCode + rightCode;
        }
        return code;
    }


    /**
     * 添加模具对应关联关系
     *
     * @param type         任务类型：0-上模、1-下模
     * @param moldChangeId 换模申请单id
     * @param taskId       换模任务id
     * @param eqpId        设备id
     * @param moldIds      模具ids
     */
    void saveMoldMp(Integer type, Long moldChangeId, Long taskId, Long eqpId, List<Long> moldIds) {
        //换模任务详情
        List<TaskChangeDetails> taskChangeDetailsList = new ArrayList<>();
        for (Long moldId : moldIds) {
            TaskChangeDetails details = new TaskChangeDetails();
            details.setMoldId(moldId);
            details.setTaskId(taskId);
            details.setMoldChangeId(moldChangeId);
            details.setEqpId(eqpId);
            details.setType(type);
            details.setId(IdGenerator.SNOW.generate());
            taskChangeDetailsList.add(details);
        }
        if (!taskChangeDetailsRepository.saveBatch(taskChangeDetailsList)) {
            throw new ServiceException("添加任务详情失败");
        }

        if (type == MoldChangeTaskTypeEnum.UP.getId()) {
            //设备模具关联表
            List<MoldEqpMp> taskEqpMoldMpList = new ArrayList<>();
            for (Long moldId : moldIds) {
                MoldEqpMp mp = new MoldEqpMp();
                mp.setMoldId(moldId);
                mp.setEqpId(eqpId);
                mp.setId(IdGenerator.SNOW.generate());
                taskEqpMoldMpList.add(mp);
            }
            if (!eqpMoldMpRepository.saveBatch(taskEqpMoldMpList)) {
                throw new ServiceException("添加设备模具关联失败");
            }
            //模具的状态
            updateMoldStatus(moldIds, MoldStatusEnum.IN_PROGRESS);
        } else {
            //根据换模申请单设备id和模具id查出来然后删掉
            LambdaQueryWrapper<MoldEqpMp> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MoldEqpMp::getEqpId, eqpId);
            queryWrapper.in(MoldEqpMp::getMoldId, moldIds);
            queryWrapper.in(MoldEqpMp::getIsDel, 0);
            List<MoldEqpMp> taskEqpMoldMps = eqpMoldMpRepository.getBaseMapper().selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(taskEqpMoldMps)) {
                List<Long> ids = new ArrayList<>();
                for (MoldEqpMp taskEqpMoldMp : taskEqpMoldMps) {
                    ids.add(taskEqpMoldMp.getId());
                }
                if (!eqpMoldMpRepository.removeByIds(ids)) {
                    throw new ServiceException("删除设备模具关联失败");
                }
            }
            //模具的状态
            updateMoldStatus(moldIds, MoldStatusEnum.FREE);
        }
    }

    /**
     * 添加任务用户关联
     *
     * @param ids
     * @param taskId
     */
    void saveTaskUserMp(List<Long> ids, Long taskId) {
        //添加到任务用户ids
        List<TaskUserMp> taskUserMpList = new ArrayList<>();
        for (Long userId : ids) {
            TaskUserMp mp = new TaskUserMp();
            mp.setTaskId(taskId);
            mp.setUserId(userId);
            mp.setId(IdGenerator.SNOW.generate());
            taskUserMpList.add(mp);
        }
        if (!userMpRepository.saveBatch(taskUserMpList)) {
            throw new ServiceException("添加任务用户失败");
        }
    }

    /**
     * 修改模具的状态
     *
     * @param moldIds
     * @param status
     */
    void updateMoldStatus(List<Long> moldIds, MoldStatusEnum status) {
        List<Mold> molds = moldRepository.listByIds(moldIds);
        if (CollectionUtil.isNotEmpty(molds)) {
            for (Mold mold : molds) {
                mold.setStatus(status.getId());
            }
            if (!moldRepository.updateBatchById(molds)) {
                throw new ServiceException("修改模具状态失败");
            }
        }
    }

    /**
     * 创建下模任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDown(CreateDownTaskParam param) {
        Long userId = SecurityUtils.getUserId();

        //根据设备id获取设备信息
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(param.getEqpId());
        if (eqpDetail == null) {
            throw new ServiceException("设备不存在");
        }

        //检查权限 技术部创建不需要检查工段了
//        checkRole(userId, eqpDetail);

        //根据设备查出进行中的换模申请单
        MoldChange moldChange = new MoldChange();
        List<MoldChange> moldChanges = moldChangeRepository.getBaseMapper().selectList(
                new LambdaQueryWrapper<MoldChange>()
                        .eq(MoldChange::getEqpId, param.getEqpId())
                        .eq(MoldChange::getStatus, MoldChangeStatusEnum.IN_PROGRESS.getId())
                        .eq(MoldChange::getIsDel, 0));
        if (CollectionUtil.isEmpty(moldChanges)) {
            throw new ServiceException("没有进行中的换模申请单");
        } else {
            moldChange = moldChanges.get(0);
        }

        if (!moldChange.getTechConfirmUserIds().contains(userId.toString())) {
            throw new ServiceException("您没有权限操作该设备");
        }

        //校验任务
        checkTask(moldChange.getId());
        moldChange.setDetailsType(MoldChangeLogDetailsTypesEnum.START_DOWN_MOLD.getId());

        //需要把当前用户加入到换修申请单得可见人ids中去
        List<Long> visibleUserIds = new ArrayList<>();
//       if (moldChange.getVisibleUserIds()!=null){
//              visibleUserIds = JSONArray.parseArray(moldChange.getVisibleUserIds(), Long.class);
//              visibleUserIds.add(userId);
//        }else {
//            visibleUserIds.add(userId);
//       }
        visibleUserIds.add(userId);
        moldChange.setVisibleUserIds(JSONArray.toJSONString(visibleUserIds));

        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }

        //创建任务
        MoldChangeTask task = new MoldChangeTask();
        BeanUtils.copyProperties(param, task);
        BeanUtils.copyProperties(eqpDetail, task);
        task.setStartTime(LocalDateTime.now());
        task.setType(MoldChangeTaskTypeEnum.DOWN.getId());
        Long id = IdGenerator.SNOW.generate();
        task.setId(id);
        String code = getCode(MoldChangeTaskTypeEnum.DOWN);
        task.setCode(code);
        task.setOperatorId(userId);
        task.setMoldChangeId(moldChange.getId());
        task.setStatus(MoldChangeStatusEnum.IN_PROGRESS.getId());
        if (!taskRepository.save(task)) {
            throw new ServiceException("创建下模任务失败");
        }

        //拿到技术部确认的ids，添加任务用户关联
//        List<Long> ids = JSONArray.parseArray(moldChange.getTechConfirmUserIds(), Long.class);
//        if (ids == null || ids.isEmpty()) {
//            throw new ServiceException("技术部确认人员为空");
//        }
//        saveTaskUserMp(ids, id);


        //把当前创建用户添加到任务关联
        List<Long> ids = new ArrayList<>();
        ids.add(userId);
        saveTaskUserMp(ids, id);

        //模具的ids
        saveMoldMp(MoldChangeTaskTypeEnum.DOWN.getId(), moldChange.getId(), id, param.getEqpId(), param.getMoldIds());
        //添加日志
        logService.saveTaskLog(id, moldChange.getId(), userId, MoldChangeLogDetailsTypesEnum.START_DOWN_MOLD, null);
    }

    /**
     * 移交任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void turnOverTask(TurnOverTaskParam param) {
        MoldChangeTask task = taskRepository.getById(param.getTaskId());
        if (task == null) {
            throw new ServiceException("任务不存在");
        }
        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        for (Long userId : param.getUserIds()) {
            //检查权限
            checkRole(userId, eqpDetail);

            List<TaskUserMp> taskUserMpList = userMpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<>(TaskUserMp.class)
                    .eq(TaskUserMp::getTaskId, param.getTaskId())
                    .eq(TaskUserMp::getUserId, userId)
                    .eq(TaskUserMp::getIsDel, 0));
            if (CollectionUtil.isNotEmpty(taskUserMpList)) {
                //如果已经存在了就不需要添加
                continue;
            }
            TaskUserMp mp = new TaskUserMp();
            mp.setTaskId(param.getTaskId());
            mp.setUserId(userId);
            mp.setId(IdGenerator.SNOW.generate());
            if (!userMpRepository.save(mp)) {
                throw new ServiceException("移交任务失败");
            }
        }
    }

    /**
     * 移交任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void turnOverTaskVisible(TurnOverTaskParam param) {
//        MoldChangeTask task = taskRepository.getById(param.getTaskId());
//        if (task == null) {
//            throw new ServiceException("任务不存在");
//        }
        // 拿到换模申请
        MoldChange moldChange = moldChangeRepository.getById(param.getTaskId());
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        String visibleUserIdsStr = moldChange.getVisibleUserIds();
        if (visibleUserIdsStr != null) {
            List<Long> visibleUserIds = JSONArray.parseArray(visibleUserIdsStr, Long.class);
            visibleUserIds.addAll(param.getUserIds());
            visibleUserIdsStr = JSONArray.toJSONString(visibleUserIds);
        } else {
            visibleUserIdsStr = JSONArray.toJSONString(param.getUserIds());
        }
        moldChange.setVisibleUserIds(visibleUserIdsStr);
        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }
    }

    /**
     * 技术工修改任务的操作员以及在最新日志疾苦被选择的操作员
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserTask(UpdateTaskUserParam param) {
        MoldChangeTask task = taskRepository.getById(param.getTaskId());
        if (task==null){
            throw new ServiceException("换模任务不存在");
        }
        //检查换模申请
        MoldChange moldChange = moldChangeRepository.getById(task.getMoldChangeId());
        if (moldChange==null){
            throw new ServiceException("换模申请单不存在");
        }
        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        if (eqpDetail==null){
            throw new ServiceException("设备信息不存在");
        }
        for (Long userId : param.getUserIds()) {
            List<TaskUserMp> taskUserMpList = userMpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<>(TaskUserMp.class)
                    .eq(TaskUserMp::getTaskId, param.getTaskId())
                    .eq(TaskUserMp::getUserId, userId)
                    .eq(TaskUserMp::getIsDel, 0));
            if (CollectionUtil.isNotEmpty(taskUserMpList)) {
                //如果已经存在了就不需要添加
                continue;
            }
            TaskUserMp mp = new TaskUserMp();
            mp.setTaskId(param.getTaskId());
            mp.setUserId(userId);
            mp.setId(IdGenerator.SNOW.generate());
            if (!userMpRepository.save(mp)) {
                throw new ServiceException("移交任务失败");
            }
        }

        //修改换模申请单的可见人ids为选择的
        moldChange.setVisibleUserIds(JSONArray.toJSONString(param.getUserIds()));
        //查询到最新一天的日志并且记录选择人ids
        MoldChangeLog lastChangeLog = logService.getLastChangeLog(moldChange.getId());
        lastChangeLog.setVisibleUserIds(JSONArray.toJSONString(param.getUserIds()));
        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }
        logService.update(lastChangeLog);

    }

    /**
     * 删除上模任务
     *
     * @param taskId
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public void deleteUpTask(Long taskId) {
        Long userId = SecurityUtils.getUserId();
        MoldChangeTask task = taskRepository.getById(taskId);
        if (task == null) {
            throw new ServiceException("任务不存在");
        }
        if (task.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的任务才能删除");
        }

        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        //检查权限
        checkRole(userId, eqpDetail);
        removeTask(task);
        //删除日志
        logService.removeLogByTaskId(taskId);
        //恢复最新进展
        resetChangeDetailsType(task.getMoldChangeId());
    }

    /**
     * 删除下模任务
     *
     * @param taskId
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public void deleteDownTask(Long taskId) {
        Long userId = SecurityUtils.getUserId();
        MoldChangeTask task = taskRepository.getById(taskId);
        if (task == null) {
            throw new ServiceException("任务不存在");
        }
        if (task.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的任务才能删除");
        }

        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        //检查权限
        checkRole(userId, eqpDetail);

        removeTask(task);
        //删除日志
        logService.removeLogByTaskId(taskId);
        //恢复最新进展
        resetChangeDetailsType(task.getMoldChangeId());
    }

    /**
     * 恢复换模的detailsType状态
     *
     * @param moldChangeId
     */
    void resetChangeDetailsType(Long moldChangeId) {
        MoldChangeLog lastChangeLog = logService.getLastChangeLog(moldChangeId);
        if (lastChangeLog != null) {
            MoldChange moldChange = moldChangeRepository.getById(moldChangeId);
            if (moldChange != null) {
                moldChange.setDetailsType(lastChangeLog.getDetailsType());
                if (!moldChangeRepository.updateById(moldChange)) {
                    throw new ServiceException("更新换模申请单状态失败");
                }
            }
        }
    }

    /**
     * 删除用户任务安排
     *
     * @param taskId
     */
    void removeTaskUserMp(Long taskId) {
        LambdaQueryWrapper<TaskUserMp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskUserMp::getTaskId, taskId);
        queryWrapper.eq(TaskUserMp::getIsDel, 0);
        List<TaskUserMp> taskUserMps = userMpRepository.getBaseMapper().selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(taskUserMps)) {
            List<Long> ids = new ArrayList<>();
            for (TaskUserMp taskUserMp : taskUserMps) {
                ids.add(taskUserMp.getId());
            }
            if (!userMpRepository.removeByIds(ids)) {
                throw new ServiceException("删除任务用户安排失败");
            }
        }
    }

    /**
     * 移除模具关联
     *
     * @param type
     * @param taskId
     * @param eqpId
     */
    void removeMold(Integer type, Long taskId, Long eqpId) {

        List<Long> moldIds = new ArrayList<>();

        //删除任务模具关联
        LambdaQueryWrapper<TaskChangeDetails> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotNull(taskId), TaskChangeDetails::getTaskId, taskId);
        queryWrapper.eq(TaskChangeDetails::getIsDel, 0);
        List<TaskChangeDetails> taskChangeDetails = taskChangeDetailsRepository.getBaseMapper().selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(taskChangeDetails)) {
            List<Long> ids = new ArrayList<>();
            for (TaskChangeDetails taskChangeDetail : taskChangeDetails) {
                ids.add(taskChangeDetail.getId());
                moldIds.add(taskChangeDetail.getMoldId());
            }
            if (!taskChangeDetailsRepository.removeByIds(ids)) {
                throw new ServiceException("删除任务模具关联失败");
            }
        }

        //判断是删除上模还是下模
        if (type == MoldChangeTaskTypeEnum.UP.getId()) {
            //如果是上模的话，把上上去的模具删掉
            LambdaQueryWrapper<MoldEqpMp> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(MoldEqpMp::getEqpId, eqpId);
            queryWrapper1.in(MoldEqpMp::getMoldId, moldIds);
            queryWrapper1.in(MoldEqpMp::getIsDel, 0);
            List<MoldEqpMp> taskEqpMoldMps = eqpMoldMpRepository.getBaseMapper().selectList(queryWrapper1);
            if (CollectionUtil.isNotEmpty(taskEqpMoldMps)) {
                List<Long> ids = new ArrayList<>();
                for (MoldEqpMp taskEqpMoldMp : taskEqpMoldMps) {
                    ids.add(taskEqpMoldMp.getId());
                }
                if (!eqpMoldMpRepository.removeByIds(ids)) {
                    throw new ServiceException("删除设备模具关联失败");
                }
            }
            //恢复模具状态为空闲
            updateMoldStatus(moldIds, MoldStatusEnum.FREE);
        } else {
            //如果是下模的话，把对应的模具新增
            //设备模具关联表
            List<MoldEqpMp> taskEqpMoldMpList = new ArrayList<>();
            for (Long moldId : moldIds) {
                MoldEqpMp mp = new MoldEqpMp();
                mp.setMoldId(moldId);
                mp.setEqpId(eqpId);
                mp.setId(IdGenerator.SNOW.generate());
                taskEqpMoldMpList.add(mp);
            }
            if (!eqpMoldMpRepository.saveBatch(taskEqpMoldMpList)) {
                throw new ServiceException("添加设备模具关联失败");
            }
            //模具的状态变成进行中
            updateMoldStatus(moldIds, MoldStatusEnum.IN_PROGRESS);
        }
    }

    /**
     * 删除任务
     *
     * @param task
     */
    void removeTask(MoldChangeTask task) {
        Long taskId = task.getId();
        taskRepository.removeById(taskId);
        //删除任务用户安排
        removeTaskUserMp(taskId);
        //删除模具
        removeMold(task.getType(), taskId, task.getEqpId());
    }

    /**
     * 删除换模申请
     *
     * @param moldChangeId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMoldChange(Long moldChangeId) {
        MoldChange moldChange = moldChangeRepository.getById(moldChangeId);
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        if (moldChange.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的换模申请单才能删除");
        }
        if (!moldChangeRepository.removeById(moldChangeId)) {
            throw new ServiceException("删除换模申请单失败");
        }

        //根据换模申请单id查出来任务
        List<MoldChangeTask> tasks = taskRepository.getBaseMapper().selectList(
                new LambdaQueryWrapper<MoldChangeTask>()
                        .eq(MoldChangeTask::getMoldChangeId, moldChangeId)
                        .eq(MoldChangeTask::getIsDel, 0));
        if (CollectionUtil.isNotEmpty(tasks)) {
            for (MoldChangeTask task : tasks) {
                removeTask(task);
            }
        }

        //删除换模申请单所有日志
        logService.removeLogByChangeId(moldChangeId);
    }

    /**
     * 获取所有空闲的模具
     *
     * @return
     */
    @Override
    public Page<MoldDetailsVo> getMoldList(GetMoldParam param) {
        GetMoldDto dto = new GetMoldDto();
        BeanUtils.copyProperties(param, dto);
        dto.setStatus(MoldStatusEnum.FREE.getId());
        Page<Mold> molds = moldRepository.selectMoldListByDto(dto);
        List<MoldDetailsVo> moldDetailsVos = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(molds.getRecords())) {
            for (Mold mold : molds.getRecords()) {
                MoldDetailsVo vo = new MoldDetailsVo();
                BeanUtils.copyProperties(mold, vo);
                vo.setMoldStatus("正常");
                moldDetailsVos.add(vo);
            }
        }
        Page<MoldDetailsVo> page = new Page<>();
        page.setRecords(moldDetailsVos);
        page.setTotal(molds.getTotal());
        return page;
    }

    /**
     * 根据模具id获取模具状态信息
     * @param moldId
     * @return
     */
    @Override
    public MoldDetailsVo getMoldStatusById(Long moldId) {
        MoldDetailsVo vo = new MoldDetailsVo();
        Mold mold = moldRepository.getById(moldId);
        if (mold != null) {
            BeanUtils.copyProperties(mold, vo);
            String moldStatus = getMoldStatus(mold);
            vo.setMoldStatus(moldStatus);
        }
        return vo;
    }

    String getMoldStatus(Mold mold) {
        if (mold.getStatus() == MoldStatusEnum.FREE.getId()) {
            return "正常";
        } else if (mold.getStatus() == MoldStatusEnum.IN_PROGRESS.getId()) {
            //检查模具当前在哪一个阶段
            TaskChangeDetails taskChangeDetails = taskChangeDetailsRepository.getBaseMapper().selectOne(
                    new LambdaQueryWrapper<TaskChangeDetails>()
                            .eq(TaskChangeDetails::getMoldId, mold.getId())
                            .eq(TaskChangeDetails::getIsDel, 0)
                            .orderByDesc(TaskChangeDetails::getCreateTime)
                            .last("limit 1"));
            if (taskChangeDetails != null) {
                MoldChangeTask task = taskRepository.getById(taskChangeDetails.getTaskId());
                if (task != null) {
                    if (task.getType() == MoldChangeTaskTypeEnum.UP.getId()) {
                        if (task.getStatus()==MoldChangeStatusEnum.IN_PROGRESS.getId()) {
                            return "上模";
                        } else if (task.getStatus() == MoldChangeStatusEnum.COMPLETED.getId()) {
                            return "使用中";
                        } else {
                            return "未知状态";
                        }
                    } else {
                        if (task.getStatus()==MoldChangeStatusEnum.IN_PROGRESS.getId()) {
                            return "下模";
                        } else if (task.getStatus() == MoldChangeStatusEnum.COMPLETED.getId()) {
                            return "正常";
                        } else {
                            return "未知状态";
                        }
                    }
                } else {
                    return "未知状态";
                }
            }
        }  else {
            return "未知状态";
        }
        return "未知状态";
    }

    /**
     * 根据设备id获取关联的模具
     *
     * @param eqpId
     * @return
     */
    @Override
    public List<MoldDetailsVo> getMoldListByEqpId(Long eqpId) {
        List<MoldDetailsVo> moldDetailsVos = new ArrayList<>();
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(eqpId);
        if (eqpDetail != null) {
            List<Mold> molds = moldRepository.selectMoldListByEqpId(eqpId);
            if (CollectionUtil.isNotEmpty(molds)) {
                for (Mold mold : molds) {
                    MoldDetailsVo vo = new MoldDetailsVo();
                    BeanUtils.copyProperties(mold, vo);
                    vo.setLocation(eqpDetail.getLocation());
                    String moldStatus = getMoldStatus(mold);
                    vo.setMoldStatus(moldStatus);
                    moldDetailsVos.add(vo);
                }
            }
        }
        return moldDetailsVos;
    }

    /**
     * 确认完成上模任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeUpTask(CompleteUpTaskParam param) {
        Long userId = SecurityUtils.getUserId();

        MoldChangeTask task = taskRepository.getById(param.getTaskId());
        if (task == null) {
            throw new ServiceException("任务不存在");
        }

        if (task.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的任务才能上模完成");
        }
        if (task.getStartTime() == null) {
            throw new ServiceException("请先开始上模");
        }

        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        //检查权限
        checkRole(userId, eqpDetail);

        task.setEndTime(LocalDateTime.now());
        task.setConfirmId(userId);
        if (!taskRepository.updateById(task)) {
            throw new ServiceException("确认完成上模任务失败");
        }

        //查询换模申请单
        MoldChange moldChange = moldChangeRepository.getById(task.getMoldChangeId());
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        moldChange.setDetailsType(MoldChangeLogDetailsTypesEnum.MOLD_UP.getId());
        //可见人ids=技术部确认人得ids
        moldChange.setVisibleUserIds(moldChange.getTechConfirmUserIds());
        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }


        //添加日志
        logService.saveTaskLog(param.getTaskId(), moldChange.getId(), userId, MoldChangeLogDetailsTypesEnum.MOLD_UP, userId);
    }

    /**
     * 确认完成下模任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeDownTask(CompleteUpTaskParam param) {
        Long userId = SecurityUtils.getUserId();
        MoldChangeTask task = taskRepository.getById(param.getTaskId());
        if (task == null) {
            throw new ServiceException("任务不存在");
        }
        if (task.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的任务才能下模完成");
        }
        if (task.getStartTime() == null) {
            throw new ServiceException("请先开始下模");
        }
        if (task.getEndTime() != null) {
            throw new ServiceException("已经下模完成，不可重复结束下模");
        }

        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        //检查权限
        checkRole(userId, eqpDetail);

        task.setEndTime(LocalDateTime.now());
        task.setConfirmId(userId);
        task.setStatus(MoldChangeStatusEnum.COMPLETED.getId());
        task.setFinishTime(LocalDateTime.now());
        task.setFinishConfirmId(userId);
        if (!taskRepository.updateById(task)) {
            throw new ServiceException("确认完成下模任务失败");
        }

        //查询换模申请单
        MoldChange moldChange = moldChangeRepository.getById(task.getMoldChangeId());
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        //可见人ids=技术部确认人得ids
        moldChange.setVisibleUserIds(moldChange.getTechConfirmUserIds());
        moldChange.setDetailsType(MoldChangeLogDetailsTypesEnum.MOLD_DOWN.getId());
        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }

        //添加日志
        logService.saveTaskLog(param.getTaskId(), moldChange.getId(), userId, MoldChangeLogDetailsTypesEnum.MOLD_DOWN, userId);

    }

    /**
     * 开始调试上模任务
     */
    @Override
    public void debugStartUpTask(Long taskId) {
        Long userId = SecurityUtils.getUserId();
        MoldChangeTask task = taskRepository.getById(taskId);
        if (task == null) {
            throw new ServiceException("任务不存在");
        }
        if (task.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的任务才能开始调试");
        }
        if (task.getDebugStartTime() != null) {
            throw new ServiceException("已经开始调试，不可重复开始调试");
        }
        if (task.getEndTime() == null) {
            throw new ServiceException("请先确认完成上模任务才能开始调试");
        }

        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        //检查权限
        checkRole(userId, eqpDetail);

        task.setDebugStartTime(LocalDateTime.now());
        task.setStatus(MoldChangeStatusEnum.IN_PROGRESS.getId());
        if (!taskRepository.updateById(task)) {
            throw new ServiceException("开始调试上模任务失败");
        }

        //查询换模申请单
        MoldChange moldChange = moldChangeRepository.getById(task.getMoldChangeId());
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        moldChange.setDetailsType(MoldChangeLogDetailsTypesEnum.START_DEBUG.getId());
        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }

        //添加日志
        logService.saveTaskLog(taskId, moldChange.getId(), userId, MoldChangeLogDetailsTypesEnum.START_DEBUG, null);
    }

    @Override
    public void debugCompleteUpTask(CompleteUpTaskParam param) {
        Long userId = SecurityUtils.getUserId();
        MoldChangeTask task = taskRepository.getById(param.getTaskId());
        if (task == null) {
            throw new ServiceException("任务不存在");
        }
        if (task.getStatus() != MoldChangeStatusEnum.IN_PROGRESS.getId()) {
            throw new ServiceException("只有进行中的任务才能调试完成");
        }
        if (task.getDebugStartTime() == null) {
            throw new ServiceException("请先开始调试");
        }
        if (task.getDebugEndTime() != null) {
            throw new ServiceException("已经调试完成，不可重复结束调试");
        }

        //查询设备
        EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
        //检查权限
        checkRole(userId, eqpDetail);

        task.setDebugEndTime(LocalDateTime.now());
        task.setDebugConfirmId(userId);
        task.setStatus(MoldChangeStatusEnum.COMPLETED.getId());
        task.setFinishTime(LocalDateTime.now());
        task.setFinishConfirmId(userId);
        if (!taskRepository.updateById(task)) {
            throw new ServiceException("调试完成上模任务失败");
        }

        //查询换模申请单
        MoldChange moldChange = moldChangeRepository.getById(task.getMoldChangeId());
        if (moldChange == null) {
            throw new ServiceException("换模申请单不存在");
        }
        moldChange.setDetailsType(MoldChangeLogDetailsTypesEnum.DEBUG_COMPLETE.getId());
        if (!moldChangeRepository.updateById(moldChange)) {
            throw new ServiceException("更新换模申请单失败");
        }

        //添加日志
        logService.saveTaskLog(param.getTaskId(), moldChange.getId(), userId, MoldChangeLogDetailsTypesEnum.DEBUG_COMPLETE, userId);
    }

    @Override
    public TaskDetailsVo getTaskDetails(Long taskId) {
        TaskDetailsVo vo = new TaskDetailsVo();
        MoldChangeTask task = taskRepository.getById(taskId);
        if (task != null) {
            BeanUtils.copyProperties(task, vo);
            vo.setTaskId(taskId);
            MoldChange moldChange = moldChangeRepository.getById(task.getMoldChangeId());
            if (moldChange != null) {
                BeanUtils.copyProperties(moldChange, vo);
                vo.setMoldChangeCode(moldChange.getCode());
                vo.setMoldChangeId(moldChange.getId());
            }
            String locationName = "";
            EqpVo eqpDetail = moldChangeRepository.getEqpDetail(vo.getEqpId());
            if (eqpDetail != null) {
                locationName = eqpDetail.getLocation();
            }
            List<MoldDetailsVo> moldDetailsVos = getMoldByTaskId(taskId, locationName);
//            setMoldStatus(task.getType(), task.getStatus(), moldDetailsVos);
            //设置模具的状态
            vo.setMoldDetailsVoList(moldDetailsVos);
        } else {
            throw new ServiceException("任务不存在");
        }
        return vo;
    }

    void setMoldStatus(Integer type, Integer status, List<MoldDetailsVo> moldDetailsVos) {
        if (CollectionUtil.isNotEmpty(moldDetailsVos)) {
            if (type == MoldChangeTaskTypeEnum.UP.getId()) {
                //检查任务是否结束
                if (status == MoldChangeStatusEnum.IN_PROGRESS.getId()) {
                    for (MoldDetailsVo moldDetailsVo : moldDetailsVos) {
                        moldDetailsVo.setMoldStatus("上模");
                    }
                } else {
                    for (MoldDetailsVo moldDetailsVo : moldDetailsVos) {
                        moldDetailsVo.setMoldStatus("使用中");
                    }
                }
            } else {
                if (status == MoldChangeStatusEnum.IN_PROGRESS.getId()) {
                    for (MoldDetailsVo moldDetailsVo : moldDetailsVos) {
                        moldDetailsVo.setMoldStatus("下模");
                    }
                } else {
                    for (MoldDetailsVo moldDetailsVo : moldDetailsVos) {
                        moldDetailsVo.setMoldStatus("正常");
                    }
                }
            }
        }
    }

    @Override
    public Page<TaskListVo> selectByPage(SelectTaskParam param) {
        //如果是admin不做数据隔离，否则只有安排或者移交的人员才能看到任务
        Long userId = SecurityUtils.getUserId();

        SelectTaskDto dto = new SelectTaskDto();
        BeanUtils.copyProperties(param, dto);

        //检查是否admin角色
        Boolean isAdmin = moldChangeRepository.getMoleRoleByUserId(userId, MoldRoleEnum.ADMIN.getName());
        if (!isAdmin) {
            dto.setUserId(userId);
        } else {
            dto.setUserId(null);
        }

        Page<TaskListVo> page = taskRepository.selectByPage(dto);
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            for (TaskListVo vo : page.getRecords()) {
                String locationName = "";
                EqpVo eqpDetail = moldChangeRepository.getEqpDetail(vo.getEqpId());
                if (eqpDetail != null) {
                    locationName = eqpDetail.getLocation();
                }
                List<MoldDetailsVo> moldDetailsVos = getMoldByTaskId(vo.getId(), locationName);
                vo.setMoldDetailsVoList(moldDetailsVos);
            }
        }
        return page;
    }

    List<MoldDetailsVo> getMoldByTaskId(Long taskId, String locationName) {
        List<MoldDetailsVo> moldDetailsVos = new ArrayList<>();
        List<TaskChangeDetails> taskChangeDetails = taskChangeDetailsRepository.getBaseMapper().selectList(new LambdaQueryWrapper<TaskChangeDetails>()
                .eq(TaskChangeDetails::getTaskId, taskId)
                .eq(TaskChangeDetails::getIsDel, 0));
        if (CollectionUtil.isNotEmpty(taskChangeDetails)) {
            List<Long> ids = taskChangeDetails.stream().map(TaskChangeDetails::getMoldId).distinct().collect(Collectors.toList());
            List<Mold> molds = moldRepository.listByIds(ids);
            if (CollectionUtil.isNotEmpty(molds)) {
                for (Mold mold : molds) {
                    MoldDetailsVo moldDetailsVo = new MoldDetailsVo();
                    BeanUtils.copyProperties(mold, moldDetailsVo);
                    moldDetailsVo.setLocation(locationName);
                    moldDetailsVos.add(moldDetailsVo);
                }
            }
        }
        return moldDetailsVos;
    }

    /**
     * 根据任务id获取操作员
     *
     * @param taskId
     * @return
     */
    @Override
    public List<UserDetailsVo> getUserListByTaskId(Long taskId) {
        List<UserDetailsVo> userDetailsVos = new ArrayList<>();
        //根据taskId获取任务用户记录
        List<TaskUserMp> taskUsers = userMpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<TaskUserMp>()
                .eq(TaskUserMp::getTaskId, taskId)
                .eq(TaskUserMp::getIsDel, 0)
        );

        if (CollectionUtil.isNotEmpty(taskUsers)) {
            List<Long> userIds = taskUsers.stream().map(TaskUserMp::getUserId).distinct().collect(Collectors.toList());
            userDetailsVos = moldChangeRepository.getUserListByIds(userIds);

        }
        return userDetailsVos;
    }

    /**
     * 移交的时候选择的用户数据-根据任务id获取不在该任务下的操作员
     *
     * @param taskId
     * @return
     */
    @Override
    public List<UserDetailsVo> getUserListByTurnOver(Long taskId) {
        List<UserDetailsVo> userDetailsVos = new ArrayList<>();
        //根据任务id查出设备信息
        MoldChangeTask task = taskRepository.getById(taskId);
        if (task != null) {
            //根据设备id查出设备信息
            EqpVo eqpDetail = moldChangeRepository.getEqpDetail(task.getEqpId());
            if (eqpDetail != null) {
                //根据设备的工段信息查出用户
                GetUserDetailsByRoleTypeDto dto = new GetUserDetailsByRoleTypeDto();
                dto.setRoleKey(MoldRoleEnum.WORKER.getName());
                dto.setLocationId(eqpDetail.getLocationId());

                Page<UserDetailsVo> page = moldChangeRepository.getOperatorByRoleKey(dto);
                List<UserDetailsVo> operatorByRoleKey = page.getRecords();
                //根据任务id获取任务用户记录
                List<TaskUserMp> taskUsers = userMpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<TaskUserMp>()
                        .eq(TaskUserMp::getTaskId, taskId)
                        .eq(TaskUserMp::getIsDel, 0)
                );
                if (CollectionUtil.isNotEmpty(operatorByRoleKey)){
                    if (CollectionUtil.isNotEmpty(taskUsers)) {
                        List<Long> userIds = taskUsers.stream().map(TaskUserMp::getUserId).distinct().collect(Collectors.toList());
                        //过滤掉已经在任务下的用户
                        for (UserDetailsVo userDetailsVo : operatorByRoleKey) {
                            if (!userIds.contains(userDetailsVo.getUserId())) {
                                userDetailsVos.add(userDetailsVo);
                            }
                        }
                    }
                }
            }
        }
        return userDetailsVos;
    }

    /**
     * 1-4-5的时候选择的用户数据-根据申请单id获取所有的上模人员和下模人员
     * @param moldChangeId
     * @return
     */
    @Override
    public List<UserDetailsVo> getUserListByDebugOver(Long moldChangeId) {
        List<UserDetailsVo> userDetailsVos = new ArrayList<>();
        //根据申请单查出下面所有任务id
        List<MoldChangeTask> tasks = taskRepository.getBaseMapper().selectList(new LambdaQueryWrapper<MoldChangeTask>()
                .eq(MoldChangeTask::getMoldChangeId, moldChangeId)
                .eq(MoldChangeTask::getIsDel, 0));

        if (CollectionUtil.isNotEmpty(tasks)) {
            List<Long> taskIds = tasks.stream().map(MoldChangeTask::getId).distinct().collect(Collectors.toList());
            //根据任务id获取任务用户记录
            List<TaskUserMp> taskUsers = userMpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<TaskUserMp>()
                    .in(TaskUserMp::getTaskId, taskIds)
                    .eq(TaskUserMp::getIsDel, 0)
            );
            if (CollectionUtil.isNotEmpty(taskUsers)) {
                List<Long> userIds = taskUsers.stream().map(TaskUserMp::getUserId).distinct().collect(Collectors.toList());
                userDetailsVos = moldChangeRepository.getUserListByIds(userIds);
            }
        }
        return userDetailsVos;
    }
}
